﻿using System.ComponentModel;
using Gavel.Common.Utilities.Model;
using Gavel.ModLink.Model;

namespace Gavel.ModLink.ViewModel;

/// <summary>
/// 寄存器数据视图模型
/// </summary>
public class RegisterViewModel : INotifyPropertyChanged
{
    /// <summary>
    /// 属性修改事件
    /// </summary>
    public event PropertyChangedEventHandler? PropertyChanged;

    /// <summary>
    /// 寄存器数据集合
    /// </summary>
    private List<RegisterValue> _values = [];

    /// <summary>
    /// 寄存器数据集合
    /// </summary>
    public List<RegisterValue> Values
    {
        get => _values;
        set
        {
            _values = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RegisterValues)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Total)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Size)));
        }
    }

    /// <summary>
    /// 分页定位
    /// </summary>
    private int _position = 1;

    /// <summary>
    /// 分页定位
    /// </summary>
    public int Position
    {
        get => _position;
        set
        {
            _position = value < 1 ? 1 : value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Position)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RegisterValues)));
        }
    }

    /// <summary>
    /// 分页大小
    /// </summary>
    private int _size = 10;

    /// <summary>
    /// 分页大小
    /// </summary>
    public int Size
    {
        get => _size;
        set
        {
            _size = value < 10 ? 10 : value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Size)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RegisterValues)));
        }
    }

    /// <summary>
    /// 数据总量
    /// </summary>
    public int Total => Values.Count;

    /// <summary>
    /// 当页数据
    /// </summary>
    public List<RegisterValue> RegisterValues
    {
        get
        {
            int position = Position < 1 ? 1 : Position;
            return Values.Skip((position - 1) * Size).Take(Size).ToList();
        }
    }

    /// <summary>
    /// 接收到数据
    /// </summary>
    /// <param name="transmit">报文传输</param>
    public void Received(MessageTransmit transmit)
    {
        ReceivedMessage message = new ReceivedMessage(transmit.Data, transmit.Protocol);
        if (message.RegisterData.Count == 0)
        {
            return;
        }

        Values = Enumerable.Range(0, message.RegisterData.Count)
            .Select(index => new RegisterValue((ushort)(transmit.Address + index), message.RegisterData[index]))
            .ToList();
    }
}